﻿using System.Collections.Generic;
using System.Linq;
using CommonFramework.Event;

namespace CommonFramework.Log
{
    public static class LogHistoryService
    {
        //最多缓存的消息数
        public const int MAX_LOGMESSAGE_CACHE_COUNT = 1024;
        //最长的缓存消息时间
        public const int MAX_LOGMESSAGE_CACHE_SECONDS = 60;

        private struct CacheMessageData
        {
            public LogMessage Msg;
            public long CachedTime;
        }
        private static List<CacheMessageData> _cachedMessages = new List<CacheMessageData>(MAX_LOGMESSAGE_CACHE_COUNT);
        private static bool _isActived = false;
        private static long _cachedTimer = 0;

        /// <summary>
        /// 服务是否在启用?
        /// </summary>
        public static bool IsActived
        {
            get => _isActived;
            set
            {
                if (_isActived != value)
                {
                    _isActived = value;
                    LogUtil.ListenLogMessage(OnLogMessage,_isActived);
                }
            }
        }

        public static void OnLogMessage(LogMessage msg,bool isBackTrace)
        {
            if (isBackTrace)
                return;

            _cachedMessages.Add(new CacheMessageData()
            {
                CachedTime = _cachedTimer,
                Msg = msg,
            });

            if(_cachedMessages.Count>MAX_LOGMESSAGE_CACHE_COUNT)
                _cachedMessages.RemoveAt(0);
        }

        public static void OnSecondUpdate()
        {
            _cachedTimer++;

            while (_cachedMessages.Count > 0 &&
                   _cachedMessages.First().CachedTime + MAX_LOGMESSAGE_CACHE_SECONDS >= _cachedTimer)
            {
                _cachedMessages.RemoveAt(0);
            }

            if (_cachedMessages.Count == 0)
                _cachedTimer = 0;
        }

        public static int GetCacheMessageCount()
        {
            return _cachedMessages.Count;
        }

        public static List<LogMessage> FilterLogMessages(Delegate.Param1WithRet<LogMessage, bool> filter)
        {
            var filtered= new List<LogMessage>();
            foreach (var cache in _cachedMessages)
            {
                if (cache.Msg != null && filter.Invoke(cache.Msg))
                {
                    filtered.Add(cache.Msg);
                }
            }
            return filtered;
        }

        public static bool ContainsServerityLog(LogSeverity severity)
        {
            foreach (var cache in _cachedMessages)
            {
                if (cache.Msg != null && cache.Msg.Severity == severity)
                    return true;
            }
            return false;
        }

        public static LogMessage FindMsgContains(string content)
        {
            if (string.IsNullOrEmpty(content))
                return null;

            foreach (var cache in _cachedMessages)
            {
                if (cache.Msg != null && cache.Msg.GetContent().Contains(content))
                    return cache.Msg;
            }
            return null;
        }
    }
}